package com.atguigu.srb.core.service.impl;

import com.atguigu.srb.base.utils.JwtUtils;
import com.atguigu.srb.common.exception.Assert;
import com.atguigu.srb.common.result.ResponseEnum;
import com.atguigu.srb.common.utils.MD5;
import com.atguigu.srb.common.utils.RegexValidateUtils;
import com.atguigu.srb.core.mapper.UserAccountMapper;
import com.atguigu.srb.core.mapper.UserInfoMapper;
import com.atguigu.srb.core.mapper.UserLoginRecordMapper;
import com.atguigu.srb.core.pojo.entity.UserAccount;
import com.atguigu.srb.core.pojo.entity.UserInfo;
import com.atguigu.srb.core.pojo.entity.UserLoginRecord;
import com.atguigu.srb.core.pojo.query.UserInfoQuery;
import com.atguigu.srb.core.pojo.vo.LoginVO;
import com.atguigu.srb.core.pojo.vo.RegisterVO;
import com.atguigu.srb.core.pojo.vo.UserIndexVO;
import com.atguigu.srb.core.pojo.vo.UserInfoVO;
import com.atguigu.srb.core.service.UserInfoService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 用户基本信息 服务实现类
 * </p>
 *
 * @author javaCode
 * @since 2025-07-19
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    private final RedisTemplate<String, Object> redisTemplate;

    private final UserAccountMapper userAccountMapper;
    private final UserLoginRecordMapper userLoginRecordMapper;

    /**
     * 会员注册
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void register(RegisterVO registerVO) {

        // 手机号
        String mobile = registerVO.getMobile();
        // 密码
        String password = registerVO.getPassword();
        // 验证码
        String code = registerVO.getCode();

        // MOBILE_NULL_ERROR(-202, "手机号不能为空"),
        Assert.notEmpty(mobile, ResponseEnum.MOBILE_NULL_ERROR);

        // MOBILE_ERROR(-203, "手机号不正确"),
        Assert.isTrue(RegexValidateUtils.checkCellphone(mobile), ResponseEnum.MOBILE_ERROR);

        // PASSWORD_NULL_ERROR(-204, "密码不能为空"),
        Assert.notEmpty(password, ResponseEnum.PASSWORD_NULL_ERROR);

        // CODE_NULL_ERROR(-205, "验证码不能为空"),
        Assert.notEmpty(code, ResponseEnum.CODE_NULL_ERROR);

        // 校验验证码
        String codeGen = (String) redisTemplate.opsForValue().get("srb:sms:code:" + mobile);
        // CODE_ERROR(-206, "验证码不正确"),
        Assert.equals(code, codeGen, ResponseEnum.CODE_ERROR);

        // 判断用户是否被注册
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getMobile, mobile);
        Integer count = this.baseMapper.selectCount(wrapper);
        // MOBILE_EXIST_ERROR(-207, "手机号已被注册"),
        Assert.isTrue(count == 0, ResponseEnum.MOBILE_EXIST_ERROR);

        // 插入用户基本信息
        UserInfo userInfo = new UserInfo();
        userInfo.setUserType(registerVO.getUserType());
        userInfo.setNickName(registerVO.getMobile());
        userInfo.setName(registerVO.getMobile());
        userInfo.setMobile(registerVO.getMobile());
        userInfo.setPassword(MD5.encrypt(registerVO.getPassword()));
        userInfo.setStatus(UserInfo.STATUS_NORMAL); // 正常

        // 设置一张静态资源服务器上的头像图片
        userInfo.setHeadImg("https://srb-file.oss-cn-beijing.aliyuncs.com/avatar/07.jpg");

        baseMapper.insert(userInfo);

        // 创建会员账户
        UserAccount userAccount = new UserAccount();
        userAccount.setUserId(userInfo.getId());
        userAccountMapper.insert(userAccount);
    }

    /**
     * 会员登录
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public UserInfoVO login(LoginVO loginVO, String ip) {
        // 手机号
        String mobile = loginVO.getMobile();
        // MOBILE_NULL_ERROR(-202, "手机号码不能为空"),
        Assert.notEmpty(mobile, ResponseEnum.MOBILE_NULL_ERROR);

        // 密码
        String password = loginVO.getPassword();
        // PASSWORD_NULL_ERROR(204, "密码不能为空"),
        Assert.notEmpty(password, ResponseEnum.PASSWORD_NULL_ERROR);

        // 用户类型
        Integer userType = loginVO.getUserType();

        // 获取会员
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getMobile, mobile).eq(UserInfo::getUserType, userType);
        UserInfo userInfo = this.baseMapper.selectOne(wrapper);

        // 用户不存在
        // LOGIN_MOBILE_ERROR(-208, "用户不存在"),
        Assert.notNull(userInfo, ResponseEnum.LOGIN_MOBILE_ERROR);

        // 校验密码
        // LOGIN_PASSWORD_ERROR(-209, "密码不正确"),
        Assert.equals(MD5.encrypt(password), userInfo.getPassword(), ResponseEnum.LOGIN_PASSWORD_ERROR);

        // 用户是否被禁用
        // LOGIN_DISABLED_ERROR(-210, "用户已被禁用"),
        Assert.equals(userInfo.getStatus(), UserInfo.STATUS_NORMAL, ResponseEnum.LOGIN_LOKED_ERROR);

        // 记录登录日志
        UserLoginRecord userLoginRecord = new UserLoginRecord();
        userLoginRecord.setUserId(userInfo.getId());
        userLoginRecord.setIp(ip);
        userLoginRecordMapper.insert(userLoginRecord);

        // 生成token
        String token = JwtUtils.createToken(userInfo.getId(), userInfo.getName());

        UserInfoVO userInfoVO = new UserInfoVO();

        userInfoVO.setToken(token);
        userInfoVO.setName(userInfo.getName());
        userInfoVO.setNickName(userInfoVO.getNickName());
        userInfoVO.setHeadImg(userInfoVO.getHeadImg());
        userInfoVO.setMobile(userInfoVO.getMobile());
        userInfoVO.setUserType(userType);

        return userInfoVO;
    }

    /**
     * 获取会员分页列表
     */
    @Override
    public IPage<UserInfo> listPage(Page<UserInfo> pageParam, UserInfoQuery userInfoQuery) {
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();

        if (userInfoQuery == null) {
            return baseMapper.selectPage(pageParam, wrapper);
        }

        // 手机号
        String mobile = userInfoQuery.getMobile();
        // 状态
        Integer status = userInfoQuery.getStatus();
        // userType
        Integer userType = userInfoQuery.getUserType();

        if (StringUtils.isNotBlank(mobile)) {
            wrapper.eq(UserInfo::getMobile, mobile);
        }

        // 修正：检查status是否为有效状态值
        if (status != null && (status == 0 || status == 1)) {
            wrapper.eq(UserInfo::getStatus, status);
        }

        // 修正：检查userType是否为有效用户类型值
        if (userType != null && (userType == 1 || userType == 2)) {
            wrapper.eq(UserInfo::getUserType, userType);
        }

        return baseMapper.selectPage(pageParam, wrapper);
    }

    /**
     * 锁定和解锁
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void lock(Long id, Integer status) {
        UserInfo userInfo = new UserInfo();

        userInfo.setId(id);
        userInfo.setStatus(status);

        this.baseMapper.updateById(userInfo);
    }

    /**
     * 校验手机号是否注册
     */
    @Override
    public boolean checkMobile(String mobile) {
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getMobile, mobile);

        return baseMapper.selectCount(wrapper) > 0;
    }

    /**
     * 获取用户信息
     */
    @Override
    public UserIndexVO getIndexUserInfo(Long userId) {
        // 用户信息
        UserInfo userInfo = baseMapper.selectById(userId);

        LambdaQueryWrapper<UserAccount> wrapper = new LambdaQueryWrapper<UserAccount>().eq(UserAccount::getUserId, userId);
        UserAccount userAccount = userAccountMapper.selectOne(wrapper);

        // 登录信息
        LambdaQueryWrapper<UserLoginRecord> userLoginRecordQueryWrapper = new LambdaQueryWrapper<>();
        userLoginRecordQueryWrapper.eq(UserLoginRecord::getUserId, userId).orderByDesc(UserLoginRecord::getId).last("limit 1");
        UserLoginRecord userLoginRecord = userLoginRecordMapper.selectOne(userLoginRecordQueryWrapper);

        // 组装结果数据
        UserIndexVO userIndexVO = new UserIndexVO();

        userIndexVO.setUserId(userInfo.getId());
        userIndexVO.setUserType(userInfo.getUserType());
        userIndexVO.setName(userInfo.getName());
        userIndexVO.setNickName(userInfo.getNickName());
        userIndexVO.setHeadImg(userInfo.getHeadImg());
        userIndexVO.setBindStatus(userInfo.getBindStatus());
        userIndexVO.setAmount(userAccount.getAmount());
        userIndexVO.setFreezeAmount(userAccount.getFreezeAmount());
        userIndexVO.setLastLoginTime(userLoginRecord.getCreateTime());

        return userIndexVO;
    }
}
